package com.zch.threaduse;

public class Thread03 {
    public static void main(String[] args) {
         //测试
//         SellTicket01 sellTicket01 = new SellTicket01();
//         SellTicket01 sellTicket02 = new SellTicket01();
//         SellTicket01 sellTicket03 = new SellTicket01();

         //这里我们会出现超卖..
//         sellTicket01.start();//启动售票线程
//         sellTicket02.start();//启动售票线程
//         sellTicket03.start();//启动售票线程
//        System.out.println("===使用实现接口方式来售票=====");
//        SellTicket02 sellTicket02 = new SellTicket02();
//        new Thread(sellTicket02).start();//第 1 个线程-窗口
//        new Thread(sellTicket02).start();//第 2 个线程-窗口
//        new Thread(sellTicket02).start();//第 3 个线程-窗口

        //测试一把
        SellTicket03 sellTicket03 = new SellTicket03();
        new Thread(sellTicket03).start();//第 1 个线程-窗口
        new Thread(sellTicket03).start();//第 2 个线程-窗口
        new Thread(sellTicket03).start();//第 3 个线程-窗口
    }
}

//实现接口方式, 使用 synchronized 实现线程同步
class SellTicket03 implements Runnable {
    private int ticketNum = 100;//让多个线程共享 ticketNum
    private boolean loop = true;//控制 run 方法变量
    //Object object = new Object();
//1.同步方法（静态的）的锁为当前类本身
//2. public synchronized static void m1() {} 锁是加在 SellTicket03.class
//3. 如果在静态方法中，实现一个同步代码块.
/*
    synchronized (SellTicket03.class) {
        System.out.println("m2");
    }
*/
    public synchronized static void m1() {
    }
    public static void m2() {
        synchronized (SellTicket03.class) {
            System.out.println("m2");
        }
    }

//1. public synchronized void sell() {} 就是一个同步方法，这时锁在 this 对象(即实例对象)
//2. 也可以在普通方法中实现同步代码块, 互斥锁还是在 this 对象
    public /*synchronized*/ void sell() {
        synchronized (this /*object*/) {
            if (ticketNum <= 0) {
                System.out.println("售票结束...");
                loop = false;
                return;
            }
//休眠 50 毫秒, 模拟
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("窗口 " + Thread.currentThread().getName() + " 售出一张票" + " 剩余票数=" + (--ticketNum));
        }
    }
    @Override
    public void run() {
        while (loop) {
            sell();//sell 方法是一个同步方法

        }
    }
}

//使用 Thread 方式
// new SellTicket01().start()
// new SellTicket01().start();
class SellTicket01 extends Thread {
    private static int ticketNum = 100;//让多个线程共享 ticketNum
    @Override
    public void run() {
        while (true) {
            if (ticketNum <= 0) {
                System.out.println("售票结束...");
                break;
            }
            //休眠 50 毫秒, 模拟
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("窗口 " + super.getName() + " 售出一张票" + " 剩余票数=" + (--ticketNum));
        }
    }
}

//实现接口方式
class SellTicket02 implements Runnable {
    private int ticketNum = 100;//让多个线程共享 ticketNum
    @Override
    public void run() {
        while (true) {
            if (ticketNum <= 0) {
                System.out.println("售票结束...");
                break;
            }
            //休眠 50 毫秒, 模拟
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("窗口 " + Thread.currentThread().getName() + " 售出一张票" + " 剩余票数=" + (--ticketNum));//1 - 0 - -1 - -2
        }
    }
}
